package cc.rboot.trigger.configuration;

import cc.rboot._core.helper.ClassHelper;
import cc.rboot._core.holder.AppContextHolder;
import cc.rboot.trigger.aspect.EventTriggerAspect;
import cc.rboot.trigger.core.IEventTrigger;
import org.springframework.aop.support.AopUtils;
import org.springframework.boot.CommandLineRunner;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import;

import java.lang.reflect.Type;
import java.util.Collections;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

@Configuration
@Import(EventTriggerAspect.class)
public class RBootEventTriggerConfiguration implements CommandLineRunner {

    private Map<Type, List<IEventTrigger>> REACTOR_MAP = new ConcurrentHashMap<>();

    @Override
    public void run(String... args) throws Exception {
        final Map<String, IEventTrigger> beans = AppContextHolder.get().getBeansOfType(IEventTrigger.class);
        beans.forEach((key, bean) -> { // public class Staff3EventReactor implements IEventTrigger<Staff, Staff2EventReactor> {
            Class beanClass = bean.getClass(); // Staff3EventReactor
            if (AopUtils.isAopProxy(bean)) {  // 处理被代理了的类
                beanClass = AopUtils.getTargetClass(bean);
            }

            Type type = ClassHelper.getTypeArgument(beanClass, 1);
            if (type != beanClass) { // 去掉回环
                List<IEventTrigger> reactiveListeners = REACTOR_MAP.get(type);
                if (reactiveListeners == null) {
                    reactiveListeners = new LinkedList<>();
                }
                reactiveListeners.add(bean);
                REACTOR_MAP.put(type, reactiveListeners); // 缓存起来，在aop中使用
            }
        });
    }

    public List<IEventTrigger> getEventReactorList(Type type) {
        if (REACTOR_MAP.containsKey(type)) {
            return REACTOR_MAP.get(type);
        }
        return Collections.emptyList();
    }

}
